//
//  main.m
//  Demo0012
//
//  Created by zTercel on 13-1-7.
//  Copyright (c) 2013年 zTercel. All rights reserved.
//

#import <Foundation/Foundation.h>

// Creating and Initializing Strings
//-----------------------------------------------------------------
// + string
// – init
// – initWithBytes:length:encoding:
// – initWithCharacters:length:
// – initWithString:
// – initWithCString:encoding:
// – initWithUTF8String:
// – initWithFormat:
// + stringWithFormat:
// + stringWithCharacters:length:
// + stringWithString:
// + stringWithCString:encoding:
// + stringWithUTF8String:
void createImmutableString()
{
    // 通过NSString常量空字串
    {
        NSString* string = [NSString string];
        NSLog(@"[%@]", string);
    }
    
    // 通过initWithBytes来生成
    {
        Byte bytes[] = {66, 'y', 't', 'e', 's', '-', 65, 's', 'c', 'i', 'i'};
        NSString* string    = [[NSString alloc] initWithBytes:bytes length:sizeof(bytes)/sizeof(Byte) encoding: NSASCIIStringEncoding];
        NSLog(@"[%@]", string);
    }
    
    // 通过initWithCharacters来生成
    {
        unichar unichars[]  = {'w', 'c', 'h', 'a', 'r', 's'};
        NSString* string    = [[NSString alloc] initWithCharacters:unichars length:sizeof(unichars)/sizeof(unichar)];
        NSString* string1   = [NSString stringWithCharacters: unichars length:sizeof(unichars)/sizeof(unichar)];
        NSLog(@"[%@] [%@]", string, string1);
    }
    
    // 通过initWithString来生成
    {
        NSString* string1   = @"create string from another string(通过另一个字串创建)";
        NSString* string    = [[NSString alloc] initWithString: string1];
        NSString* string2   = [NSString stringWithString: string1];
        NSLog(@"[%@] [%@]", string, string2);
    }
    
    // 通过C字符串来生成
    {
        char* cstring       = "C characters-can't support chinese 中国";
        NSString* string    = [[NSString alloc] initWithCString: cstring encoding: NSASCIIStringEncoding];  // encoding = NSUTF8String can show chinese character
        NSString* string1   = [NSString stringWithCString: cstring encoding: NSASCIIStringEncoding];
        NSLog(@"[%@] [%@]", string, string1);
    }
    
    // 通过C字符串来生成
    {
        char* UTF8String    = "UTF8-字符串";
        NSString* string    = [[NSString alloc] initWithUTF8String: UTF8String];
        NSString* string1   = [NSString stringWithUTF8String: UTF8String];
        NSLog(@"[%@] [%@]", string, string1);
    }
    
    // 通过NSString常量创建对象
    {
        NSString* string    = @"const NSString object";
        NSLog(@"[%@]", string);
    }
    
    // 通过initWithFormat
    {
        NSString* string    = [[NSString alloc] initWithFormat: @"(%d) %s", 1, "using initWithFormat method"];
        NSString* string1   = [NSString stringWithFormat: @"(%d) %s", 1, "using initWithFormat method"];
        NSLog(@"[%@] [%@]", string, string1);
    }
    
    return;
}

// Getting a String’s Length
//--------------------------------------------
// – length
// – lengthOfBytesUsingEncoding:
// – maximumLengthOfBytesUsingEncoding:
void getStringLength()
{
    NSString* string1 = @"This is a NSString Object-计算本字串的长度";
    
    NSLog(@"%@ length = %ld, unicode length = %li max utf8 length = %li", string1, [string1 length], [string1 lengthOfBytesUsingEncoding: NSUnicodeStringEncoding], [string1 maximumLengthOfBytesUsingEncoding: NSUTF8StringEncoding]);
    
    return;
}

// Getting Characters and Bytes
//--------------------------------------------
// – characterAtIndex:
// – getCharacters:range:
void getCharactersAndBytes()
{
    NSString* string    = @"getCharatersAndBytes";
    NSLog(@"%@ index[3] = %c", string, [string characterAtIndex:3]);
    
    unichar* buffer = malloc(10);
    memset(buffer, 0, sizeof(unichar) * 10);
    [string getCharacters:buffer range:NSMakeRange(3,9)];
    NSLog(@"%@ range[3, 9] = %@", string, [NSString stringWithCharacters:buffer length:10]);
    free(buffer);
    
    return;
}

//Getting C Strings
//--------------------------------------------
// – cStringUsingEncoding:
// – getCString:maxLength:encoding:
// – UTF8String
void getCString()
{
    NSString* string    = @"this is a NSString object, convert it to cstring";
    
    NSLog(@"%@  %s", string, [string cStringUsingEncoding:NSASCIIStringEncoding]);
    
    NSInteger length    = [string lengthOfBytesUsingEncoding:NSASCIIStringEncoding];
    char* buffer        = malloc(length);
    [string getCString:buffer maxLength:length encoding:NSASCIIStringEncoding];
    NSLog(@"%@  %s", string, buffer);
    free(buffer);
    
    NSLog(@"%@  %s", string, [string UTF8String]);
    
    return;
}

//append Strings
//------------------------------------------------
// – stringByAppendingFormat:
// – stringByAppendingString:
// – stringByPaddingToLength:withString:startingAtIndex:
void appendString()
{
    NSString* string1   = @"this is a string";
    string1 = [string1 stringByAppendingString:@"+ using stringByAppendingString method append to string"];
    // string1 = [string1 insertValue: &value atIndex: 18 inPropertyWithKey: nil];
    string1 = [string1 stringByAppendingFormat:@" length = (%li)", [string1 length]];
    NSLog(@"%s", [string1 cStringUsingEncoding:NSASCIIStringEncoding]);
    
    NSString* string2   = @"stringByPaddingToLength";
    NSLog(@"%@  [%@]",  string2, [string2 stringByPaddingToLength:[string2 length] * 2 withString:@"." startingAtIndex:0]);
    
    return;
}


//divide Strings
//------------------------------------------------
// – componentsSeparatedByString:
// – substringFromIndex:
// – substringWithRange:
// – substringToIndex:
void divideString()
{
    NSString* string    = @"this is a NSString Object";
    NSLog(@"source: [%@] substringToIndex[%d]: [%@]", string, 4, [string substringToIndex:4]);
    NSLog(@"source: [%@] substringWithRange[Range(%d  %ld)]: %@", string, 5, [string length] - 11, [string substringWithRange:NSMakeRange(5, [string length] - 11)]);
    NSLog(@"source: [%@] substringFromIndex[%ld]: [%@]", string, [string length] - 6, [string substringFromIndex:[string length] - 6]);
    
    NSArray* array = [string componentsSeparatedByString: @" "];
    for (NSString* str in array)
    {
         NSLog(@"componentSeparatedByString: [%@]", str);
    }
    
    return;
}

// Finding Characters
//-------------------------------------------------
// - rangeOfString:options:range
void findString()
{
    NSString* string1 = [NSString stringWithFormat:@"A life, a fulfilling life, a rich life includes ups and downs, includes pain and getting up again, includes failure and getting up again"];
    NSString* string2 = @"life";
    
    NSInteger time = 0;
    NSRange rangeOccur  = NSMakeRange(0, [string1 length]);
    long nextPos = 0;
    do {
        rangeOccur = [string1 rangeOfString:string2 options:NSCaseInsensitiveSearch range: NSMakeRange(nextPos, [string1 length] - nextPos)];
        if (NSNotFound != rangeOccur.location)
        {
            NSLog(@"time(%li) =  %li", time++, rangeOccur.location);
            nextPos = rangeOccur.location + rangeOccur.length;
        }
    } while (rangeOccur.location != NSNotFound);
        
    return;
}

// Replacing Substrings
//------------------------------------------------
// – stringByReplacingOccurrencesOfString:withString:options:range:
// – stringByReplacingCharactersInRange:withString:
void replaceString()
{
    NSString*   string  = @"replaceString stringByReplacingOccurrencesOfString";
    NSLog(@"[%@]  [%@]", string, [string stringByReplacingCharactersInRange:NSMakeRange(0, 13) withString:@"string"]);
    NSLog(@"[%@]  [%@]", string, [string stringByReplacingOccurrencesOfString:@"string" withString:@"Characters" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [string length])]);
    
    return;
}

// comparing Strings
//------------------------------------------------
// – caseInsensitiveCompare:
// – localizedCaseInsensitiveCompare:
// – compare:
// – compare:options:range:
// – isEqualToString:
// – hasPrefix
// - hasSuffix
void compareStrings()
{
    NSString*   string1 = @"Greg.yi";
    NSString*   string2 = @"greg.yi";
    
    // caseInsensitiveCompare/localizedCaseInsensiteCompare 不分大小与比较
    switch ([string1 caseInsensitiveCompare: string2])
    {
        case NSOrderedAscending:
            NSLog(@"caseInsensitiveCompare %@ < %@", string1, string2);
            break;
        case NSOrderedSame:
            NSLog(@"caseInsensitiveCompare %@ = %@", string1, string2);
            break;
        case NSOrderedDescending:
            NSLog(@"caseInsensitiveCompare %@ > %@", string1, string2);
            break;
    }

    // compare:options:range:
    switch ([string1 compare:string2 options: NSCaseInsensitiveSearch range: NSMakeRange(0, [string1 length])]) {  // 从string1中提取Range范围数据与string2不分大小写比较
        case NSOrderedAscending:
            NSLog(@"compare:options:range: %@ < %@", string1, string2);
            break;
        case NSOrderedSame:
            NSLog(@"compare:options:range: %@ = %@", string1, string2);
            break;
        case NSOrderedDescending:
            NSLog(@"compare:options:range: %@ > %@", string1, string2);
            break;
    }
    
    // compare 根据ascii码从左到右比较大小
    switch ([string1 compare: string2])
    {
        case NSOrderedAscending:
            NSLog(@"%@ < %@", string1, string2);
            break;
        case NSOrderedSame:
            NSLog(@"%@ = %@", string1, string2);
            break;
        case NSOrderedDescending:
            NSLog(@"%@ > %@", string1, string2);
            break;
    }

    // isEqualToString 
    NSLog(@"string1(%@) is equal to string2(%@)? %s", string1, string2, [string1 isEqualToString:string2] ? "Yes" : "No");
    
    NSString* prefixString  = @"Greg";
    NSLog(@"string1(%@) is contain to prefix string (%@)? %s", string1, prefixString, [string1 hasPrefix: prefixString] ? "Yes" : "No");
    
    NSString* suffixString  = @"yi";
    NSLog(@"string1(%@) is contain to suffix string (%@)? %s", string1, suffixString, [string1 hasSuffix: suffixString] ? "Yes" : "No");

    return;
}

// Changing Case
//------------------------------------------------
// – capitalizedString
// – lowercaseString
// – uppercaseString
void caseString()
{
    NSString* string    = @"this is a NSString object";
    NSLog(@"%@ lowercase: %@", string, [string lowercaseString]);
    NSLog(@"%@ uppercase: %@", string, [string uppercaseString]);
    NSLog(@"%@ capitalized: %@", string, [string capitalizedString]);
    
    return;
}

//Getting Numeric Values
//------------------------------------------------
// – doubleValue
// – floatValue
// – intValue
// – integerValue
// – longLongValue
// – boolValue
void getNumberValueOfString()
{
    {
        NSString* string = @"12.2399";
        NSLog(@"string %@ convert to double %f", string, [string doubleValue]);
    }
    
    {
        NSString* string = @"120000";
        NSLog(@"string %@ convert to int %d", string, [string intValue]);
    }
    
    {
        NSString* string = @"1";
        NSLog(@"string %@ convert to bool %s", string, [string boolValue] ? "yes" : "no");
    }
    
    return;
}

NSMutableString* outputTriangle(int lineCount)
{
    NSMutableString* triangleString = [NSMutableString new];
    [triangleString appendFormat:@"\n"];
    for (int ii = 0; ii < lineCount; ii++)
    {
        for (int jj = 0; jj < lineCount - ii; jj++)
        {
            [triangleString appendFormat: @"%s", " "];
        }
        
        for (int kk = 0; kk <= ii * 2; kk++)
        {
            [triangleString appendFormat: @"%s", "*"];
        }
        [triangleString appendFormat:@"\n"];
    }
    
    return triangleString;
}

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        NSLog(@"----------------create string----------------");
        createImmutableString();
       
        NSLog(@"----------------string length----------------");
        getStringLength();

        NSLog(@"----------------string characters----------------");
        getCharactersAndBytes();
        
        NSLog(@"----------------c string characters----------------");
        getCString();
        
        NSLog(@"----------------append string----------------");
        appendString();
        
        NSLog(@"----------------Divide string----------------");
        divideString();
        
        NSLog(@"----------------compare string----------------");
        compareStrings();

        NSLog(@"----------------replace string----------------");
        replaceString();
        
        NSLog(@"----------------case string----------------");
        caseString();
        
        NSLog(@"----------------retreve number from string----------------");
        getNumberValueOfString();
        
        
        NSMutableString* triangleString = outputTriangle(16);
        NSLog(@"%s", [triangleString UTF8String]);
        
        NSString* str = [NSString stringWithFormat: @"ztercel_%s", "ytercel"];
        NSLog(@"[%@]", str);
    }
    return 0;
}

